# THIS SCRIPT COMPUTES SUMMARY STATISTICS FOR FIGURE 5, AND PROVIDES
# THE SYNTAX FOR CREATING THE FIGURE ITSELF. IT MUST BE RUN IN CONJUNCTION 
# WITH THE DATASET "ANESCumulative_cleaned.csv", AVAILABLE IN THE REPLICATION 
# MATERIALS ON DATAVERSE. 
rm(list = ls())
library(foreign)
library(car)
library(readstata13)
library(ggplot2)
library(stargazer)
library(grid)
library(gridExtra)
library(survey)
library(dplyr)
library(lemon)
library(ggpubr)
library(reshape2)

# READ IN THE DATA. SELECT THE FILE "ANESCumulative_cleaned.csv"
our.data = read.csv(file.choose())
######################################################################################
######################################################################################
######################################################################################
######################################################################################
######################################################################################
# POLITICAL KNOWLEDGE

# DESIGN
our.design = svydesign(ids=~1, weight=~our.data$VCF0009z,
                       data = our.data)

# REPUBLICANS
our.means.republicans = svyby(~politicalknowledge, ~as.factor(programmatic) + year, 
                              svymean, design = subset(our.design, republican==1), na.rm = TRUE)
our.means.republicans = as.data.frame(our.means.republicans)
# DEMOCRATS
our.means.democrats = svyby(~politicalknowledge, ~as.factor(programmatic) + year, 
                            svymean, design = subset(our.design, democrat==1), na.rm = TRUE)
our.means.democrats = as.data.frame(our.means.democrats)
# BIND THE TWO DATASETS
means.data = rbind(our.means.republicans, our.means.democrats)
means.data$partisanship = c(rep("Republicans", 60), 
                            rep("Democrats", 60))
# YEAR
means.data$year = as.numeric(as.character(means.data$year))
names(means.data)[1] = "programmatic"
means.data$programmatic = car::recode(means.data$programmatic,
                                      "0 = 'Unmatched';
                                      0.5 = 'Partially matched';
                                      1 = 'Matched'; else = NA")
# REMOVE EMPTY YEARS; CLEAN UP
means.data.knowledge = subset(means.data, politicalknowledge!=0)
means.data.knowledge$item = rep("Political knowledge (no. of correct responses)", 
                               length(means.data.knowledge$year))
names(means.data.knowledge)[3] = "average"
means.data.knowledge = means.data.knowledge[-c(4)]
######################################################################################
######################################################################################
######################################################################################
######################################################################################
######################################################################################
# LOW-LEVEL ACTIVISM

# DESIGN
our.design = svydesign(ids=~1, weight=~our.data$VCF0009z,
                       data = our.data)

# REPUBLICANS
our.means.republicans = svyby(~lla, ~as.factor(programmatic) + year, 
                              svymean, design = subset(our.design, republican==1), na.rm = TRUE)
our.means.republicans = as.data.frame(our.means.republicans)
# DEMOCRATS
our.means.democrats = svyby(~lla, ~as.factor(programmatic) + year, 
                            svymean, design = subset(our.design, democrat==1), na.rm = TRUE)
our.means.democrats = as.data.frame(our.means.democrats)
# BIND THE TWO DATASETS
means.data = rbind(our.means.republicans, our.means.democrats)
means.data$partisanship = c(rep("Republicans", 60), 
                            rep("Democrats", 60))
# YEAR
means.data$year = as.numeric(as.character(means.data$year))
names(means.data)[1] = "programmatic"
means.data$programmatic = car::recode(means.data$programmatic,
                                      "0 = 'Unmatched';
                                      0.5 = 'Partially matched';
                                      1 = 'Matched'; else = NA")
# REMOVE EMPTY YEARS; CLEAN UP
means.data.lla = subset(means.data, lla!=0)
means.data.lla$item = rep("Low-level activism (no. of activities)", 
                          length(means.data.lla$year))
names(means.data.lla)[3] = "average"
means.data.lla = means.data.lla[-c(4)]
######################################################################################
######################################################################################
######################################################################################
######################################################################################
######################################################################################
# INTERVIEWER ASSESSMENT, RESPONDENTS' POLITICAL KNOWLEDGE

# DESIGN
# SUBSET, JUST FTF INTERVIEW DATA
FTFinterview.data = subset(our.data, is.na(our.data$VCF0009x)=="FALSE")
our.design = svydesign(ids=~1, weight=~FTFinterview.data$VCF0009x,
                       data = FTFinterview.data)

# POSITION, REPUBLICANS
our.means.republicans = svyby(~interviewerobs.pre, ~as.factor(programmatic) + year, 
                              svymean, design = subset(our.design, republican==1), na.rm = TRUE)
our.means.republicans = as.data.frame(our.means.republicans)
# POSITION, DEMOCRATS
our.means.democrats = svyby(~interviewerobs.pre, ~as.factor(programmatic) + year, 
                            svymean, design = subset(our.design, democrat==1), na.rm = TRUE)
our.means.democrats = as.data.frame(our.means.democrats)
# BIND THE TWO DATASETS
means.data = rbind(our.means.republicans, our.means.democrats)
means.data$partisanship = c(rep("Republicans", 57), 
                            rep("Democrats", 57))
# YEAR
means.data$year = as.numeric(as.character(means.data$year))
names(means.data)[1] = "programmatic"
means.data$programmatic = car::recode(means.data$programmatic,
                                      "0 = 'Unmatched';
                                      0.5 = 'Partially matched';
                                      1 = 'Matched'; else = NA")
# REMOVE EMPTY YEARS; CLEAN UP
means.data.interviewerobs.pre = subset(means.data, interviewerobs.pre!=0)
means.data.interviewerobs.pre$item = rep("Political information (interviewer rating)", 
                                         length(means.data.interviewerobs.pre$year))
names(means.data.interviewerobs.pre)[3] = "average"
means.data.interviewerobs.pre = means.data.interviewerobs.pre[-c(4)]
######################################################################################
######################################################################################
######################################################################################
######################################################################################
######################################################################################
# EDUCATIONAL ATTAINMENT: % WITH BACHELOR'S DEGREE

# DESIGN
our.design = svydesign(ids=~1, weight=~our.data$VCF0009z,
                       data = our.data)

# PROPORTIONS, REPUBLICANS
our.means = svytable(~ hasBA + year + as.factor(programmatic), design = subset(our.design, republican==1))
republicans.props = prop.table(our.means, 2:3)
republicans.props = as.data.frame(republicans.props)
# PROPORTIONS, DEMOCRATS
our.means = svytable(~ hasBA + year + as.factor(programmatic), design = subset(our.design, democrat==1))
democrats.props = prop.table(our.means, 2:3)
democrats.props = as.data.frame(democrats.props)
# BIND THE TWO DATASETS
means.data = rbind(republicans.props, democrats.props)
means.data = subset(means.data, hasBA=="Has BA")
means.data$partisanship = c(rep("Republicans", 60), 
                            rep("Democrats", 60))
# YEAR
means.data$year = as.numeric(as.character(means.data$year))
names(means.data)[3] = "programmatic"
means.data$programmatic = car::recode(means.data$programmatic,
                                      "0 = 'Unmatched';
                                      0.5 = 'Partially matched';
                                      1 = 'Matched'; else = NA")
# CLEAN UP DATA...
attach(means.data)
means.data.hasBA = data.frame(programmatic, year, Freq, partisanship)
means.data.hasBA$item = rep("Proportion with four-year degree", length(means.data.hasBA$year))
names(means.data.hasBA)[3] = "average"
detach(means.data)
######################################################################################
######################################################################################
######################################################################################
######################################################################################
######################################################################################
# INTEREST IN PUBLIC AFFAIRS: % SAYING 'MOST OF THE TIME'

# SUBSET, JUST FTF INTERVIEW DATA
FTFinterview.data = subset(our.data, is.na(our.data$VCF0009x)=="FALSE")
# DESIGN
our.design = svydesign(ids=~1, weight=~FTFinterview.data$VCF0009x,
                       data = FTFinterview.data)

# PROPORTIONS, REPUBLICANS
our.means = svytable(~ interest.publicaffairs + year + as.factor(programmatic), design = subset(our.design, republican==1))
republicans.props = prop.table(our.means, 2:3)
republicans.props = as.data.frame(republicans.props)
# PROPORTIONS, DEMOCRATS
our.means = svytable(~ interest.publicaffairs + year + as.factor(programmatic), design = subset(our.design, democrat==1))
democrats.props = prop.table(our.means, 2:3)
democrats.props = as.data.frame(democrats.props)
# BIND THE TWO DATASETS
means.data = rbind(republicans.props, democrats.props)
means.data = subset(means.data, interest.publicaffairs=="4. Most of the time")
means.data$partisanship = c(rep("Republicans", 51), 
                            rep("Democrats", 51))
# YEAR
means.data$year = as.numeric(as.character(means.data$year))
names(means.data)[3] = "programmatic"
means.data$programmatic = car::recode(means.data$programmatic,
                                      "0 = 'Unmatched';
                                      0.5 = 'Partially matched';
                                      1 = 'Matched'; else = NA")
# CLEAN UP DATA...
attach(means.data)
means.data.interest.publicaffairs = data.frame(programmatic, year, Freq, partisanship)
means.data.interest.publicaffairs$item = rep("Proportion follow public affairs 'most of the time'", length(means.data.interest.publicaffairs$year))
names(means.data.interest.publicaffairs)[3] = "average"
detach(means.data)
######################################################################################
######################################################################################
######################################################################################
######################################################################################
######################################################################################
# INTEREST IN ELECTIONS: % SAYING 'VERY MUCH INTERESTED'

# DESIGN
our.design = svydesign(ids=~1, weight=~our.data$VCF0009z,
                       data = our.data)

# PROPORTIONS, REPUBLICANS
our.means = svytable(~ interest.elections + year + as.factor(programmatic), design = subset(our.design, republican==1))
republicans.props = prop.table(our.means, 2:3)
republicans.props = as.data.frame(republicans.props)
# PROPORTIONS, DEMOCRATS
our.means = svytable(~ interest.elections + year + as.factor(programmatic), design = subset(our.design, democrat==1))
democrats.props = prop.table(our.means, 2:3)
democrats.props = as.data.frame(democrats.props)
# BIND THE TWO DATASETS
means.data = rbind(republicans.props, democrats.props)
means.data = subset(means.data, interest.elections=="3. Very much interested")
means.data$partisanship = c(rep("Republicans", 57), 
                            rep("Democrats", 57))
# YEAR
means.data$year = as.numeric(as.character(means.data$year))
names(means.data)[3] = "programmatic"
means.data$programmatic = car::recode(means.data$programmatic,
                                      "0 = 'Unmatched';
                                      0.5 = 'Partially matched';
                                      1 = 'Matched'; else = NA")
# CLEAN UP DATA...
attach(means.data)
means.data.interest.elections = data.frame(programmatic, year, Freq, partisanship)
means.data.interest.elections$item = rep("Proportion 'very much interested' in elections", length(means.data.interest.elections$year))
names(means.data.interest.elections)[3] = "average"
detach(means.data)
######################################################################################
######################################################################################
######################################################################################
######################################################################################
######################################################################################
# MERGE 
new.data = rbind(means.data.hasBA, 
                 means.data.knowledge, 
                 means.data.interviewerobs.pre,
                 means.data.lla,
                 means.data.interest.elections,
                 means.data.interest.publicaffairs)
new.data$year = as.numeric(as.character(new.data$year))

# FIGURE 5: ALTERNATE METRICS OF POLITICAL SOPHISTICATION, 1972-2020.
library(tidyverse)
library(ggh4x)
library(lemon)
our.plot = ggplot(subset(new.data, year>=1972),
                  aes(year, average, group = partisanship, 
                      linetype =  partisanship)) +
  geom_line(aes(linetype = partisanship), linewidth = 0.8) +
  labs(linetype = "Partisanship") + 
  xlab("Year") +
  ylab("") +
  # ggtitle("Alternate Metrics of Political Sophistication, 1972-2020, \nBy Partisanship and Matching Status", 
  #        subtitle = "Data: ANES cumulative file, partisan identifiers only. \nAll continuous variables recoded to range between 0-1") + 
  theme_minimal() +  
  scale_color_grey(start = 0.5, end = 0.8) +
  ylab("Proportion") + 
  facet_nested_wrap(~item + programmatic, nrow = 6) +
  theme(legend.title = element_text(face = "bold", size = 9)) +
  theme(legend.position = "top") +
  # theme(legend.title = element_text(size = 9)) +
  # theme(legend.text = element_text(size = 9)) +
  theme(axis.title.x = element_text(size = 9)) + 
  theme(axis.title.y = element_text(size = 9)) +
  # theme(plot.title = element_text(hjust = 0.5, face = "bold", size = 14)) + 
  # theme(plot.subtitle = element_text(hjust = 0.5, size = 12)) +
  theme(strip.text = element_text(face = "bold", size = 9)) + 
  theme(strip.text.y.right = element_text(angle = 0, hjust = 0)) + 
  theme(panel.spacing.x = unit(1, "lines"))
our.plot

# SAVE
# ggsave(our.plot, file = "Schmidtetal-Figure5.pdf", width = 6.6, height = 9)
